package com.swgk.core.base.api;

import com.swgk.core.util.MD5Utils;
import com.swgk.core.util.MLog;

import org.apache.commons.lang3.RandomStringUtils;

import java.util.Date;

import cn.hutool.crypto.symmetric.AES;

/**
 * AES 加解密工具类
 * 功能：
 *   1.承载AES加解密方法，
 *     加密见 encodeAES(String content)，
 *     解密见 decodeAES(String content)，传入的是要加密解密字符
 *   2.提供签名生成方式，见方法 getSignStr()
 */
public class AESUtils {

    private static final String TAG = AESUtils.class.getSimpleName();

    /**
     * 工作模式
     */
    private static final String AES_KEY_WORK_TYPE = "CBC";
    /**
     * 填充方式
     */
    private static final String AES_KEY_IV_TYPE = "PKCS7Padding";

    /**
     * AES偏移量
     */
    private static final String AES_IV_VALUE = "bc3f07fbe54c4b90";

    /**
     * AES公钥
     */
    public static final String AES_KEY = "8985b2c4fb1900cf";

    /**
     * 服务器验签公钥
     */
    private static final String SIGN_PUBLIC_KEY = "7%NAdOte&&6*5g!K3ZFzOgiWJ3mL0kol";

    /**
     * 生成公钥
     * 拼接格式：自定义字符 + "｜" + 服务器验签公钥
     * 注意本签名的自定义字符为：时间戳+32位随机字符
     * @param value 需要于签名公钥拼接字符
     * @return 返回将拼接起来的MD5后的
     */
    private static String encodeMD5(String value){
        return MD5Utils.encrypt(value + "|" + SIGN_PUBLIC_KEY);
    }

    /**
     * 生成sign
     * 生成原则：
     *  1.获取当前时间戳
     *  2.生成32位随机字符
     *  3.将时间戳+生成的随机字符直接拼接，通过"时间戳+32位随机字符+"｜"+服务器验签公钥"进行MD5加密生成签名公钥
     *  4.将时间戳，随机字符，MD5密文通过"&"字符拼接生成签名
     * @return 返回签名
     */
    public static String getSignStr(){
        //获取当前时间戳
        long timeStamp = new Date().getTime();
        //生成 32为随机字符
        String nonceStr = RandomStringUtils.randomAlphanumeric(32);
        // 对时间戳和数字字符的拼接进行MD5加密（输出原密文，不用输出大写）
        String clientSign = encodeMD5(timeStamp + nonceStr);
        // 拼接时间戳和32位随机字符以及生成的MD5密文作为sign;
        String sign = timeStamp + "&" + nonceStr + "&" + clientSign;
        if (MLog.DEBUG_LOG) {
            MLog.d(TAG,  "接口加密签名  = " + sign);
        }
        return sign;
    }

    /**
     * 加密
     * @param content 要加密的字符明文
     * @return 返回加密后的密文
     */
    public static String encodeAES(String content){
        AES aes = new AES(AES_KEY_WORK_TYPE, AES_KEY_IV_TYPE,AES_KEY.getBytes(),AES_IV_VALUE.getBytes());
        String encryptHex = aes.encryptHex(content);
        return encryptHex;
    }

    /**
     * 解密
     * @param content 要解密的密文
     * @return 返回解密后的明文
     */
    public static String decodeAES(String content){
        AES aes = new AES(AES_KEY_WORK_TYPE, AES_KEY_IV_TYPE,AES_KEY.getBytes(),AES_IV_VALUE.getBytes());
        String decryptStr = aes.decryptStr(content);
        return decryptStr;
    }
}
